package com.jzt.jk.open.api.controller;

import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.*;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;

/**
 * 作者：lizw <br/>
 * 创建时间：2021/01/18 15:35 <br/>
 */
@RestController
public class RoutesManageController {
    private final InMemoryRouteDefinitionRepository routeDefinitionRepository;
    private final CachingRouteLocator cachingRouteLocator;
    private int id = 0;

    public RoutesManageController(InMemoryRouteDefinitionRepository routeDefinitionRepository, RouteLocator routeLocator) throws URISyntaxException {
        Assert.isTrue(routeLocator instanceof CachingRouteLocator, "参数routeLocator类型转换错误");
        this.routeDefinitionRepository = routeDefinitionRepository;
        this.cachingRouteLocator = (CachingRouteLocator) routeLocator;
        id++;
        RouteDefinition routeDefinition = new RouteDefinition();
        routeDefinition.setId("baidu");
        routeDefinition.setUri(new URI("https://www.baidu.com"));
        routeDefinition.setOrder(id);
        routeDefinition.getFilters().add(new FilterDefinition("StripPrefix=1"));
        routeDefinition.getPredicates().add(new PredicateDefinition("Path=/baidu/**"));
        Mono<RouteDefinition> route = Mono.just(routeDefinition);
        routeDefinitionRepository.save(route).then(clear().then()).subscribe();
    }

    @PostMapping("/api/route_definition_add")
    public Mono<String> addRouteDefinition() throws Exception {
        RouteDefinition routeDefinition = new RouteDefinition();
        routeDefinition.setId("test-" + (id++));
        routeDefinition.setUri(new URI("http://127.0.0.1:" + (8401 + id)));
        routeDefinition.setOrder(id);
        routeDefinition.getFilters().add(new FilterDefinition("PreserveHostHeader"));
        routeDefinition.getFilters().add(new FilterDefinition("DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Access-Control-Allow-Methods Access-Control-Allow-Headers"));
        routeDefinition.getPredicates().add(new PredicateDefinition("Host=aa.com,bb.com"));
        Mono<RouteDefinition> route = Mono.just(routeDefinition);
        return routeDefinitionRepository.save(route).then(clear().then()).thenReturn("OK");
    }

    @GetMapping("/api/test")
    public Mono<String> test() {
        return Mono.empty().thenReturn("OK");
    }

    @PostMapping("/api/route_definition/add_weibo")
    public Mono<String> addWeibo() throws Exception {
        RouteDefinition routeDefinition = new RouteDefinition();
        routeDefinition.setId("test-" + (id++));
        routeDefinition.setUri(new URI("https://weibo.com"));
        routeDefinition.setOrder(id);
        routeDefinition.getFilters().add(new FilterDefinition("StripPrefix=1"));
        routeDefinition.getPredicates().add(new PredicateDefinition("Path=/weibo/**"));
        Mono<RouteDefinition> route = Mono.just(routeDefinition);
        return routeDefinitionRepository.save(route).then(clear().then()).thenReturn("OK");
    }

    @PostMapping("/api/route_definition/add_baidu")
    public Mono<String> addBaidu() throws Exception {
        RouteDefinition routeDefinition = new RouteDefinition();
        routeDefinition.setId("test-" + (id++));
        routeDefinition.setUri(new URI("https://www.baidu.com"));
        routeDefinition.setOrder(id);
        routeDefinition.getFilters().add(new FilterDefinition("StripPrefix=1"));
        routeDefinition.getPredicates().add(new PredicateDefinition("Path=/baidu/**"));
        Mono<RouteDefinition> route = Mono.just(routeDefinition);
        return routeDefinitionRepository.save(route).then(clear().then()).thenReturn("OK");
    }

    @PostMapping("/api/route_definition/del_baidu")
    public Mono<String> delBaidu() {
        return routeDefinitionRepository.delete(Mono.just("baidu")).then(clear().then()).thenReturn("OK");
    }

    protected Flux<Route> clear() {
        return cachingRouteLocator.refresh();
    }
}
